from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtGui import QIcon

from UI.show_tab_sensor import TabSensor
from manager.NetManager import *


class WorkThread(QThread):
    signal_info = pyqtSignal(object, object)
    signal_sensor = pyqtSignal(object)

    def __init__(self, dict_para: dict):
        super(WorkThread, self).__init__()
        self.b_loop = True
        self.dict_para = dict_para
        self.buff_size = 1024
        pass

    def __del__(self):
        self.dict_para.clear()
        print('clear dict!!!')

    def set_loop(self, bloop: bool):
        self.b_loop = bloop

    def run(self):
        while self.b_loop:
            if self.dict_para['type'] == NET_TYPE.TCP_SERVER:
                pass
            elif self.dict_para['type'] == NET_TYPE.TCP_CLIENT:
                pass
            elif self.dict_para['type'] == NET_TYPE.UDP:
                rev_data, dict_sensor = NetManager().rev_data(self.dict_para['type'])
                print('rev_data:', rev_data)
                if rev_data != '':
                    self.signal_info.emit(self.dict_para['type'], rev_data)
                    # if len(dict_sensor) != 0:
                    #     self.signal_sensor.emit(dict_sensor)
            time.sleep(0.7)


class TabNet(object):
    _instance_lock = threading.Lock()
    _first_init = True

    def __init__(self):
        if self._first_init:
            self.ui = None
            self.b_open_con = True
            self.rev_con_info = ""
            self.thread = None
            pass
        pass

    def __del__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with cls._instance_lock:
                if not hasattr(cls, '_instance'):
                    TabNet._instance = super().__new__(cls)
        return TabNet._instance

    def init_ui(self, ui):
        self.ui = ui
        self.init_ui_net()
        self.init_connect()

    def init_ui_net(self):
        self.ui.cobx_type.addItems(['TCP客户端', 'TCP服务器', 'UDP'])
        self.ui.t_btn_ip_fresh.setIcon(QIcon("./res/fresh.png"))
        # self.ui.t_btn_ip_fresh.setIconSize(QSize(18, 18))
        # self.ui.t_btn_ip_fresh.setFixedSize(QSize(18, 18))
        # self.ui.chbx_show_ascii.setChecked(True)
        self.ui.chbox_show_time.setChecked(True)
        self.ui.chbox_save_log.setChecked(True)
        self.ui.cobx_type.setEditable(False)
        self.ui.cobx_type.setCurrentIndex(0)
        self.ui.chbox_show_ip.setChecked(True)
        self.ui.chbox_show_port.setChecked(True)

    def init_connect(self):
        self.ui.btn_open_close_con.clicked.connect(self.btn_open_close_con_clicked)
        self.ui.btn_send.clicked.connect(self.btn_send_clicked)

    def isValid(self, ip, port):
        if ip == "":
            self.ui.statusbar.showMessage("No Tcp server IP input!!!")
            return
        elif port == "":
            self.ui.statusbar.showMessage("No Tcp server port input!!!")
            return

    def btn_open_close_con_clicked(self):
        # invalid input
        ip = self.ui.ledit_ip.text().strip()
        port = self.ui.ledit_port.text().strip()
        self.isValid(ip, port)
        if self.b_open_con:  # connect
            current_index = self.ui.cobx_type.currentIndex()
            if current_index == NET_TYPE.TCP_SERVER.value:
                NetManager().tcp_server_connect(ip, int(port))
            elif current_index == NET_TYPE.TCP_CLIENT.value:
                NetManager().tcp_client_connect(ip, int(port))
            elif current_index == NET_TYPE.UDP.value:
                NetManager().udp_connect(ip, int(port))
            self.b_open_con = False
            self.ui.btn_open_close_con.setText("断开")
            dict_para = {'type': NET_TYPE(current_index)}
            self.thread = WorkThread(dict_para)
            self.thread.signal_info.connect(self.update_info)
            self.thread.signal_sensor.connect(self.update_sensor)
            self.thread.start()
        else:  # disconnect
            self.thread.set_loop(False)
            self.thread.quit()
            # self.thread.wait()
            NetManager().close_socket()
            self.b_open_con = True
            self.ui.btn_open_close_con.setText("连接")
        pass

    def btn_send_clicked(self):
        pass

    @staticmethod
    def update_sensor(dict_sensor):
        TabSensor().update_sensor_status(dict_sensor)

    def update_info(self, net_type: int, info):
        len_rev = len(info)
        if net_type == NET_TYPE.UDP:
            if self.ui.chbox_show_hex.isChecked():
                print(len_rev)
                if len_rev:
                    data_str = Common.bytes_to_str(info)
                    info = data_str + '\n'
            else:
                try:
                    info = str(info, encoding='utf-8')
                except UnicodeDecodeError:
                    info = ''
                    for i in range(0, len_rev):
                        info += '$'
            info = time.strftime("%Y_%m_%d %H:%M:%S", time.localtime()) + ' ' + info
            if self.ui.chbox_save_log.isChecked():
                Common.save_txt(info)
            self.rev_con_info = self.rev_con_info + info
            self.ui.tbr_rev.setText(self.rev_con_info)
            self.ui.tbr_rev.moveCursor(self.ui.tbr_rev.textCursor().End)
